package com.sparrow.websocket;

import com.alibaba.fastjson.JSONObject;
import com.sparrow.bean.*;
import com.sparrow.exception.ChannelNotExistException;
import com.sparrow.exception.IllegalOperationMessageException;
import com.sparrow.exception.UnFullWebsocketMessageException;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * Created by wancheng on 2019/3/13.
 */
public class TextWebSocketFrameHandler  extends
        SimpleChannelInboundHandler<TextWebSocketFrame> {

    public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private RoomManage roomManage = RoomManage.getInstance();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx,
                                TextWebSocketFrame msg) throws Exception {
        Channel incoming = ctx.channel();
        String msgBody = msg.text();
        Message message = JSONObject.parseObject(msgBody,Message.class);
        if (message.getOption() == null){
            throw new UnFullWebsocketMessageException();
        }

        switch (message.getOption()){
            case REGISTER:
                if (message.getLessonId() == null || message.getRole() == null){
                    throw new UnFullWebsocketMessageException();
                }
                roomManage.register(message,incoming);
                break;
            case SEND:
                roomManage.send(channels,incoming,message);
                break;
            case DESTROY:
                roomManage.destroy(message.getLessonId());
                break;
            default:
                throw new IllegalOperationMessageException();
        }

    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        channels.add(incoming);
        System.out.println("Client:"+incoming.remoteAddress() +"加入");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println("Client:"+incoming.remoteAddress() +"离开");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println("Client:"+incoming.remoteAddress()+"在线");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println("Client:"+incoming.remoteAddress()+"掉线");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        Channel incoming = ctx.channel();
        Message message = new Message();
        Member member = roomManage.getMember(incoming.id());
        message.setRole(member.getRole());
        message.setAccount(member.getAccount());
        message.setLessonId(member.getRoomId());
        message.setName(member.getName());
        message.setCode(SocketStatus.SOCKET_ERROR);
        Exception e = new Exception(cause);
        if (e instanceof ChannelNotExistException ){
            message.setMsg("连接断开,请重新开启连接");
            incoming.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(member)));
        }else if(e instanceof IllegalOperationMessageException){
            message.setMsg("非法的操作");
            incoming.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(member)));
        }else if(e instanceof UnFullWebsocketMessageException){
            message.setMsg("消息信息不完整!");
            incoming.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(member)));
        }else{
            message.setMsg("内部异常,连接断开!");
            message.setCode(SocketStatus.SOCKET_EXCEPTION);
            incoming.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(member)));
            ctx.close();
        }
        cause.printStackTrace();
    }
}
